package pathcheck;

sub new {
my $proto=shift;
my %args=@_;
my $class=ref($proto) || $proto;
my $self={};

	if(!exists($args{PATH}) || !exists($args{NODE})) {
		return undef;
	}
	$self->{PATH}=$args{PATH};
	$self->{NODE}=$args{NODE};
	if(!exists($args->{CMD})) {
		$self->{CMD}="/opt/linuxha14/bin/utils/pathinfo";
	} else {
		$self->{CMD}=$args{CMD};
	}
	bless($self,$class);
	return $self;
}

sub _getidlists {
my $path=$_[0];
my $cpath="";
my $ppath="";
my @uids=();
my @gids=();
my @perms=();
my @sb;

	for $celement ("/",split(/\//,$path)) {
		next if !defined($celement) || $celement eq "";
		if($celement ne "/") {
			$cpath.="/$celement";
		} else {
			$cpath.=$celement;
		}
		@sb=stat($cpath);
		if(!defined($sb[0])) {
			return ($ppath);
		}
		push @uids,$sb[4];
		push @gids,$sb[5];
		push @perms,$sb[2] & 07777;
		$ppath=$cpath;
	}
	return (\@uids,\@gids,\@perms);
}

sub _getremoteinfo {
my $path=$_[0];
my $cmd=$_[1];
my $node=$_[2];
my $cpath="";
my $ppath="";
my @uids=();
my @gids=();
my @perms=();
my @sb;

	$r=`ssh $node -o batchmode=yes "ls $cmd 2>/dev/null"`;
	if($r eq "") {
		return undef;
	}
	for $celement ("/",split(/\//,$path)) {
		next if !defined($celement) || $celement eq "";
		if($celement ne "/") {
			$cpath.="/$celement";
		} else {
			$cpath.=$celement;
		}
		$r=`ssh $node -o batchmode=yes "$cmd $cpath 2>/dev/null"`;
		if($r eq "") {
			return ($ppath);
		}
		chomp $r;
		@sb=split(/,/,$r);
		push @uids,$sb[0];
		push @gids,$sb[1];
		push @perms,$sb[2];
		$ppath=$cpath;
	}
	return (\@uids,\@gids,\@perms);
}

sub check {
my $self=shift;
my ($luids,$lgids,$lperms);
my ($ruids,$rgids,$rperms);
my @errs=();
my ($x,$cpath,$celement,$lpp);

	($luids,$lgids,$lperms)=_getidlists($self->{PATH});
	if(!defined($lgids)) {
		push @errs,"Only $luids part of ".$self->{PATH}." exists locally!";
	}
	($ruids,$rgids,$rperms)=_getremoteinfo($self->{PATH},$self->{CMD},$self->{NODE});
	if(!defined($ruids)) {
		push @errs,"Specified info command does not exist on ".$self->{NODE};
	} else {
		if(!defined($rgids)) {
			push @errs,"Only $ruids part of ".$self->{PATH}." exists on ".$self->{NODE};
		}
	}
	if(scalar(@errs)) {
		return @errs;
	}

	#################################################################
	# At this point we know that both paths exist on both nodes	#
	# so we now ensure that the uid, gid and owner are the same	#
	# as well...							#
	#################################################################
	
	$x=0; $cpath="";
	for $celement ("/",split(/\//,$self->{PATH})) {
		next if !defined($celement) || $celement eq "";
		if($celement ne "/") {
			$cpath.="/$celement";
		} else {
			$cpath.=$celement;
		}
		if($$luids[$x] ne $$ruids[$x]) {
			push @errs,"Uids differ for $cpath [local=".$$luids[$x].",remote=".$$ruids[$x]."]";
		}
		if($$lgids[$x] ne $$rgids[$x]) {
			push @errs,"Gids differ for $cpath [local=".$$lgids[$x].",remote=".$$rgids[$x]."]";
		}
		$lpp=sprintf("%04o",$$lperms[$x]);
		if($lpp ne $$rperms[$x]) {

			push @errs,"Permissions differ for $cpath [local=$lpp,remote=".$$rperms[$x]."]";
		}
		$x++;
	}
	return @errs;
}

1;
